package com.xwj.coupon.user.framework.ratelimit;

import com.xwj.coupon.user.framework.exception.ClientException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Description TODO
 * @Author xwj
 * @Date 2025/8/23
 */
@Aspect
@Slf4j
@Component
public class RateLimitAspect {

    @Autowired
    private RateLimitService rateLimitService;

    @Around(value = "@annotation(com.xwj.coupon.user.framework.ratelimit.RateLimit)")
    public Object rateLimit(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature)(joinPoint.getSignature());
        Method method = signature.getMethod();
        RateLimit rateLimit = method.getAnnotation(RateLimit.class);
        if(rateLimit!=null){
            String resource = rateLimit.resource();
            if(resource.isEmpty()){
                resource = method.getName();
            }
            int windowSize = rateLimit.windowSize();
            int maxRequests = rateLimit.maxRequests();
            log.info("限流配置，资源：{}，窗口大小：{}，最大请求数：{}",resource,windowSize,maxRequests);
            if(!rateLimitService.allowRequest(resource,windowSize,maxRequests)){
                throw new ClientException(rateLimit.msg());
            }
            return joinPoint.proceed();
        }
        else{
            log.warn("方法{}上未找到限流注解",method.getName());
            return null;
        }
    }
}
